/**
 * @Description: api 多节点控制，支持同一个请求，短时间重复的过滤
 */
import axios from "axios";
import qs from "qs";
import md5 from "md5";
import config from "@/config";
import { Message } from "iview";
import Cookies from "js-cookie";
import { TOKEN_KEY } from "@/libs/util";

//发送请求的管理，同一请求在没有返回的情况下或者超时返回，不能反复请求
let requestManagement = {};
const CancelToken = axios.CancelToken;

//API 全局配置
//https://www.easy-mock.com/mock/5add9213ce4d0e69998a6f51/iview-admin/
axios.defaults.baseURL = config.baseURL;
axios.defaults.timeout = 60000;
axios.defaults.withCredentials = true;
axios.defaults.transformRequest = [
  function(data, headers) {
    //return a string or an axios of Buffer, ArrayBuffer,FormData or Stream
    //return JSON.stringify(data);
    return qs.stringify(data);
    //return data;
  }
];

//请求拦截器
axios.interceptors.request.use(
  function(config) {
    console.log("request", config);
    config = requestUrl(config);
    return config;
  },
  function(error) {
    return Promise.reject(error);
  }
);

//返回拦截器
axios.interceptors.response.use(
  function(response) {
    console.log("response", response);
    responseUrl(response.config);
    return response;
  },
  function(error) {
    return Promise.reject(error);
  }
);

/*
 * 拦截相同API  测试在test模块中
 * 存在2个模块初始化都请求一个API，会存在问题，这类情况很少，注意即可。
 * 暴露请求状态对象出去，可以控制每个请求的状态，(切换路由终止/时间长度终止）
 * 建议：有些是依赖初始化异步懒加载，发送成功后，人为终止或许更多问题需要处理, 比如增加白名单
 */
function requestUrl(config) {
  let requestId = md5(config.url + config.data);
  if (requestManagement[requestId]) {
    requestManagement[requestId].cancel("阻塞重复异步请求#" + config.url);
  } else {
    let cancel = new CancelToken(c => {
      return c;
    });
    requestManagement[requestId] = { cancel: cancel, createTime: new Date() };
    /* 测试请求发送成功后又取消，测试是OK的
        setTimeout(function(){
            requestManagement[requestId].cancel('测试发送出去后，在终止请求');
        },100);
        */
  }
  config.requestId = requestId;
  return config;
}

//响应后，删除请求
function responseUrl(config) {
  if (requestManagement[config.requestId]) {
    delete requestManagement[config.requestId];
  }
}

//axios请求封装
function request(data) {
  return new Promise((resolve, reject) => {
    console.log(data);
    axios(data)
      .then(function(response) {
        let { data } = response;
        if (data.code !== 200) {
          if (data.code === 401) {
            Cookies.remove(TOKEN_KEY);
            window.location.href = "/#/login";
            Message.error("未登录，或登录失效，请登录");
          } else {
            if (data.msg) Message.error(data.msg);
          }
          return false;
        }
        resolve(data);
      })
      .catch(function(error) {
        if (axios.isCancel(error)) {
          console.log("Request canceled", error.message);
        } else {
          Message.error("服务内部错误");
          //alert("Oops! There was a problem on the request. Please check the " + data.url);
          console.log("Request error:", data.url, error);
        }
        reject(err);
      });
  });
}

/****************************** 基础平台 api **************************/
//下面的API可以按照模块分解也可以集中管理,各有优势

//API login
export const login = obj => {
  let requestData = {
    method: "post",
    url: "login",
    data: obj
  };
  return request(requestData);
};

//API getUserInfo
export const getUserInfo = obj => {
  let requestData = {
    method: "get",
    url: "get_info",
    params: obj
  };
  return request(requestData);
};

export const logout = obj => {
  let requestData = {
    method: "get",
    url: "logout"
  };
  return request(requestData);
};
